#include "xparameters.h"
#include "xuartlite.h"
#include "xil_io.h"
#include "xil_printf.h"

#define UART_DEVICE_ID      XPAR_AXI_UARTLITE_0_DEVICE_ID
#define BRAM_BASEADDR       XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR
#define IMG_PIXELS          (28*28)

int main(void) {
    XUartLite Uart;
    int bytes_received;
    u8 byte;
    u32 addr = 0;
    u8 header[5] = {0};

    // 初始化 UART Lite
    XUartLite_Initialize(&Uart, UART_DEVICE_ID);
    xil_printf("UART->BRAM 接收程序启动...\r\n");

    // 等待接收 'START'
    xil_printf("等待帧头 START...\r\n");
    while (1) {
        byte = XUartLite_RecvByte(Uart.RegBaseAddress);
        // 滑动窗口匹配"START"
        for (int i = 0; i < 4; ++i) header[i] = header[i+1];
        header[4] = byte;
        if (header[0]=='S' && header[1]=='T' && header[2]=='A' && header[3]=='R' && header[4]=='T') break;
    }
    xil_printf("检测到 START，开始接收图像数据...\r\n");

    // 接收 IMG_PIXELS 字节并写入 BRAM
    for (int i = 0; i < IMG_PIXELS; ++i) {
        // 阻塞接收
        while ((bytes_received = XUartLite_Recv(&Uart, &byte, 1)) == 0);
        Xil_Out8(BRAM_BASEADDR + i, byte);
    }
    xil_printf("图像数据 (%d bytes) 已写入 BRAM\r\n", IMG_PIXELS);

    // 等待接收 'END'
    xil_printf("等待帧尾 END...\r\n");
    // 重用 header 缓冲
    for (int i = 0; i < 3; ++i) header[i]=0;
    while (1) {
        byte = XUartLite_RecvByte(Uart.RegBaseAddress);
        for (int i = 0; i < 2; ++i) header[i] = header[i+1];
        header[2] = byte;
        if (header[0]=='E' && header[1]=='N' && header[2]=='D') break;
    }
    xil_printf("检测到 END，接收完成。\r\n");
    sleep(1);
    // 发送ACK给上位机
    const u8 ack_msg[] = "DONE";
    XUartLite_Send(&Uart, ack_msg, 4);
    //xil_printf("DONE。\r\n");
    sleep(1);
    while (1) {
        // 可加入额外逻辑或睡眠
    }
    return 0;
}
